import { AudioClip } from 'cc';
import { AudioSource } from 'cc';
import { _decorator, Component, Node } from 'cc';
import { local_bool, local_num, local_set } from '../localData/LocalData';
import ResLoader from '../resource/ResLoader';
const { ccclass, property } = _decorator;

@ccclass('EffectAudioSource')
export class EffectAudioSource extends Component {
    // 声音开关
    private _enableKey: string = '__sgame_effect_enable';
    private _enable: boolean = true;
    public get enable(): boolean {
        return this._enable;
    }

    public set enable(enable: boolean) {
        this._enable = enable;
        local_set(this._enableKey, enable);
    }

    // 背景音乐大小
    private _volumnKey: string = '__sgame_effect_volumn';
    private _volumn: number = 1;
    public get volumn(): number {
        return this._volumn;
    }

    public set volumn(volumn: number) {
        this._volumn = volumn;
        this._audioSource.volume = volumn;
        local_set(this._volumnKey, volumn);
    }

    private audios: Map<string, AudioClip> = new Map<string, AudioClip>();
    private _audioSource: AudioSource;

    protected onLoad(): void {
        this._audioSource = this.addComponent(AudioSource);
        this.enable = local_bool(this._enableKey, true);
        this.volumn = local_num(this._volumnKey, 1);
    }

    public async play(audio: AudioClip | string, volumeScale: number = 1) {
        if (!this._enable) {
            return; // 直接忽略
        }

        if (this._volumn <= 0) {
            return; // 直接忽略
        }

        if (typeof audio === 'string') {
            if (this.audios.has(audio)) {
                audio = this.audios.get(audio);
            } else {
                const audioPath: string = audio;
                audio = await ResLoader.LoadAssetSync(audio, AudioClip);
                this.audios.set(audioPath, audio);
            }
        }

        this._audioSource.playOneShot(audio, volumeScale);
    }

    public release(path: string) {
        if (this.audios.has(path)) {
            this.audios.delete(path);
        }
    }

    public releaseByBundle(bundleName: string) {
        for (const audioPath of this.audios.keys()) {
            if (audioPath.startsWith(bundleName)) {
                this.audios.delete(audioPath);
            }
        }
    }

    public clear() {
        this.audios.clear();
    }
}